import { IpcRenderer } from "electron";

// 定义与 preload 脚本一致的 IPC 接口
interface IpcRendererApi {
  on(channel: string, listener: (event: any, ...args: any[]) => void): void;
  off(channel: string, ...args: any[]): void;
  send(channel: string, ...args: any[]): void;
  invoke(channel: string, ...args: any[]): Promise<any>;
}

// 扩展 Window 接口
declare global {
  interface Window {
    electronAPI: {
      ipcRenderer: IpcRendererApi;
      window: {
        create(options: {
          url: string;
          windowId?: string;
          width?: number;
          height?: number;
          modal?: boolean;
          webPreferences?: Electron.WebPreferences;
          data?: any;
        }): Promise<{ success: boolean; windowId?: string; error?: string }>;
        close(windowId: string): Promise<{ success: boolean; error?: string }>;
        getInfo(windowId: string): Promise<{
          success: boolean;
          data?: {
            id: string;
            x: number;
            y: number;
            width: number;
            height: number;
            isMaximized: boolean;
            isMinimized: boolean;
            isVisible: boolean;
          };
          error?: string;
        }>;
        getInitialData(): any;
        sendMessage(
          windowId: string,
          channel: string,
          ...args: any[]
        ): Promise<{ success: boolean; error?: string }>;
        broadcastMessage(
          channel: string,
          ...args: any[]
        ): Promise<{ success: boolean; error?: string }>;
        onMessage(channel: string, callback: (data: any) => void): void;
      };
    };
  }
}

// 定义IPC通信的返回类型
interface IpcResponse {
  status: "success" | "error";
  message: string;
  data?: any;
}

/**
 * Electron通信工具类 - 单例模式
 */
class ElectronUtils {
  private static instance: ElectronUtils;
  private ipcRenderer: IpcRendererApi;

  private constructor() {
    this.ipcRenderer = window.electronAPI?.ipcRenderer;
    if (!this.ipcRenderer) {
      throw new Error("IpcRenderer is not available");
    }
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): ElectronUtils {
    if (!ElectronUtils.instance) {
      ElectronUtils.instance = new ElectronUtils();
    }
    return ElectronUtils.instance;
  }

  /**
   * 发送同步消息到主进程
   * @param channel 通道名
   * @param args 参数
   */
  public send(channel: string, ...args: any[]): void {
    this.ipcRenderer.send(channel, ...args);
  }

  /**
   * 发送异步消息到主进程并等待响应
   * @param channel 通道名
   * @param args 参数
   * @returns Promise<IpcResponse>
   */
  public async invoke(channel: string, ...args: any[]): Promise<IpcResponse> {
    return await this.ipcRenderer.invoke(channel, ...args);
  }

  /**
   * 监听主进程消息
   * @param channel 通道名
   * @param listener 处理函数
   */
  public on(
    channel: string,
    listener: (event: any, ...args: any[]) => void
  ): void {
    this.ipcRenderer.on(channel, listener);
  }

  /**
   * 移除主进程消息监听
   * @param channel 通道名
   * @param listener 处理函数
   */
  public off(
    channel: string,
    listener: (event: any, ...args: any[]) => void
  ): void {
    this.ipcRenderer.off(channel, listener);
  }

  /**
   * 创建新窗口
   * @param options 窗口选项
   * @returns Promise<{ success: boolean; windowId?: string; error?: string }>
   */
  public async createWindow(options: {
    url: string;
    windowId?: string;
    width?: number;
    height?: number;
    modal?: boolean;
  }): Promise<{ success: boolean; windowId?: string; error?: string }> {
    return await window.electronAPI.window.create(options);
  }

  /**
   * 关闭窗口
   * @param windowId 窗口ID
   * @returns Promise<{ success: boolean; error?: string }>
   */
  public async closeWindow(
    windowId: string
  ): Promise<{ success: boolean; error?: string }> {
    return await window.electronAPI.window.close(windowId);
  }

  /**
   * 获取窗口信息
   * @param windowId 窗口ID
   * @returns Promise<{
   *   success: boolean;
   *   data?: {
   *     id: string;
   *     x: number;
   *     y: number;
   *     width: number;
   *     height: number;
   *     isMaximized: boolean;
   *     isMinimized: boolean;
   *     isVisible: boolean;
   *   };
   *   error?: string;
   * }>
   */
  public async getWindowInfo(windowId: string): Promise<{
    success: boolean;
    data?: {
      id: string;
      x: number;
      y: number;
      width: number;
      height: number;
      isMaximized: boolean;
      isMinimized: boolean;
      isVisible: boolean;
    };
    error?: string;
  }> {
    return await window.electronAPI.window.getInfo(windowId);
  }
}

// 导出单例实例
export default ElectronUtils.getInstance();
